package com.dongbao.util;

import cn.hutool.json.JSONUtil;
import com.dongbao.entity.TreeNode;
import com.intellij.lang.properties.parsing.PropertiesTokenTypes;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.source.javadoc.PsiDocCommentImpl;
import com.intellij.psi.impl.source.tree.PsiCommentImpl;
import org.xmind.core.ITopic;
import org.xmind.core.internal.dom.TopicImpl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TreeNodeUtil {

  /** 匹配流程图插件注解的正则表达式 */
  public static final String isFlowPatter = "FLOW(:|\\(\\{.*\\}\\):|：|；|;)";

  public static final String todoPatter = "@todo(.*)";

  public static final String warnPatter = "@warn(.*)";

  public static final String corePatter = "@core(.*)";
  /*获取类名**/
  public static final String classPatter = "@class\\((.*)\\)";
  /** 匹配出流程图注解中的JSON信息的表达式 */
  public static final String flowJsonPatter = "FLOW\\(\\{.*\\}\\)";

  /** 读取节点中声明的ID与parentId */
  public static TreeNode readerDoucument(PsiElement element) {
    if (element instanceof PsiCommentImpl) {
      PsiCommentImpl commentElement = (PsiCommentImpl) element;
      String text = commentElement.getText();
      Pattern pattern = Pattern.compile(flowJsonPatter, Pattern.CASE_INSENSITIVE); // 创建匹配数字字符的模式
      Matcher matcher = pattern.matcher(text);
      String jsonInfo = null;
      while (matcher.find()) // matcher.find()用于查找是否有这个字符，有的话返回true
      {
        // 查找到节点中有对象的配置
        jsonInfo = text.substring(matcher.start(), matcher.end());
        jsonInfo = jsonInfo.substring(0, jsonInfo.length() - 1).replace("FLOW(", "");
      }
      if (jsonInfo == null) {
        return null;
      }
      TreeNode treeNode = JSONUtil.toBean(jsonInfo, TreeNode.class);
      return treeNode;
    }
    return null;
  }

  /** 读取节点中的内容信息 */
  public static String readerNodeContent(PsiElement element) {
    if (element instanceof PsiCommentImpl || element instanceof PsiDocCommentImpl) {
      String text = "";
      if(element instanceof PsiDocCommentImpl){
        text = ((PsiDocCommentImpl) element).getText();
      }else{
        text =  ((PsiCommentImpl) element).getText();
      }

      Pattern pattern = Pattern.compile(isFlowPatter, Pattern.CASE_INSENSITIVE); // 创建匹配数字字符的模式
      Matcher matcher = pattern.matcher(text);
      String jsonInfo = null;
      while (matcher.find()) // matcher.find()用于查找是否有这个字符，有的话返回true
      {
        // 查找到节点中有对象的配置
        return text.substring(matcher.end(), text.length());
      }
      return null;
    }
    return null;
  }
  /** 读取节点中的类名 */
  public static String getClassName( String text ) {
      Pattern pattern = Pattern.compile(classPatter, Pattern.CASE_INSENSITIVE); // 创建匹配数字字符的模式
      Matcher matcher = pattern.matcher(text);
      while (matcher.find()) // matcher.find()用于查找是否有这个字符，有的话返回true
      {
        // 查找到节点中有对象的配置
        return matcher.group(1);
      }
    return null;
  }
  /**
   * @description:
   * @author: lirufei
   * @date: 2023/4/19 17:02
   * @param: src
   * @param: patter
   * @return
   */
  public static String replaceString(String src, String patter) {
    Pattern pattern = Pattern.compile(patter, Pattern.CASE_INSENSITIVE); // 创建匹配数字字符的模式
    Matcher matcher = pattern.matcher(src);
    //把符合正则的数据替换成""
    while(matcher.find()){
      src = src.replace(matcher.group(), matcher.group(1));
    }
    return src;
  }
  public static String replaceClassName(String src, String patter) {
    Pattern pattern = Pattern.compile(patter, Pattern.CASE_INSENSITIVE); // 创建匹配数字字符的模式
    Matcher matcher = pattern.matcher(src);
    //把符合正则的数据替换成""
    while(matcher.find()){
      src = src.replace(matcher.group(), "");
    }
    return src;
  }
  /** 给一个节点创建一个ID对象 */
  public static TreeNode createId(PsiElement element) {
    return createId(element, null);
  }

  public static TreeNode createId(PsiElement element, Long parentId) {
    // 创建一个TreeNode节点对象
    if (element instanceof PsiCommentImpl) {
      PsiCommentImpl commentElement = (PsiCommentImpl) element;
      String text = commentElement.getText();
      TreeNode treeNode = new TreeNode();
      treeNode.setId(IDUtils.genItemId());
      if (parentId != null) {
        treeNode.setParentId(parentId);
      }
      return treeNode;
    }
    // 将ID信息添加到Element中
    return null;
  }

  /** 将Node对象写入到标签中 */
  public static void writerDocument(TreeNode treeNode, PsiElement element, AnActionEvent event) {
    if (element instanceof PsiCommentImpl) {
      String text = element.getText();
      Pattern pattern = Pattern.compile(isFlowPatter, Pattern.CASE_INSENSITIVE); // 创建匹配数字字符的模式
      Matcher matcher = pattern.matcher(text);
      Boolean isExis = false;
      String content = null;
      while (matcher.find()) // matcher.find()用于查找是否有这个字符，有的话返回true
      {
        int start = matcher.start();
        int end = matcher.end();
        content = text.substring(end, text.length());
        break;
      }
      // 重新组装前缀并替换原始内容
      String prefix = createPrefix(treeNode);

      PsiCommentImpl commentImpl =
          new PsiCommentImpl(PropertiesTokenTypes.END_OF_LINE_COMMENT, prefix + content);
      String finalContent = content;
      WriteCommandAction.runWriteCommandAction(
          event.getProject(),
          new Runnable() {
            @Override
            public void run() {
              ((PsiCommentImpl) element).replaceWithText(prefix + finalContent);
            }
          });
    }
    System.out.println("6666");
  }

  /** 判断一个PsiElement 是否是flowChat的节点 */
  public static boolean isFlowNode(PsiElement element) {
    String text = element.getText();
    Pattern pattern = Pattern.compile(isFlowPatter, Pattern.CASE_INSENSITIVE); // 创建匹配数字字符的模式
    Matcher matcher = pattern.matcher(text);

    while (matcher.find()) // matcher.find()用于查找是否有这个字符，有的话返回true
    {
      return true;
    }
    return false;
  }

  /**
   * @description: 判断正则表达式是否出现
   * @author: lirufei
   * @date: 2023/4/19 16:59
   * @param: text
   * @return
   */
  public static boolean checkPatter(String text , String patter) {
    Pattern pattern = Pattern.compile(patter, Pattern.CASE_INSENSITIVE); // 创建匹配数字字符的模式
    Matcher matcher = pattern.matcher(text);
    while (matcher.find()) // matcher.find()用于查找是否有这个字符，有的话返回true
    {
      return true;
    }
    return false;
  }
  /** 生成一个固定前缀 */
  public static String createPrefix(TreeNode treeNode) {
    return "//FLOW(" + JSONUtil.toJsonStr(treeNode) + "):";
  }

  /** 判断一个PsiElement 注释注释对象是否存在id信息 */
  public static boolean isExistId(PsiElement element) {
    // 创建一个TreeNode节点对象
    if (element instanceof PsiCommentImpl) {
      PsiCommentImpl commentElement = (PsiCommentImpl) element;
      String text = commentElement.getText();
      Pattern pattern = Pattern.compile(flowJsonPatter, Pattern.CASE_INSENSITIVE); // 创建匹配数字字符的模式
      Matcher matcher = pattern.matcher(text);
      Boolean isExis = false;
      while (matcher.find()) // matcher.find()用于查找是否有这个字符，有的话返回true
      {
        // 查找到节点中有对象的配置
        isExis = true;
      }
      return isExis;
    }
    return false;
  }

  /** 持续查找上级节点,如果上级节点的root（往上查找,一直到没有parentId的节点)在当前的待处理Map中,则删除 */
  public static boolean isDeleteNode(Map<ITopic, TreeNode> relaseNode, TreeNode parentTreeNode) {
    for (ITopic topic : relaseNode.keySet()) {
      TreeNode treeNode = relaseNode.get(topic);
      if (treeNode.getId().equals(parentTreeNode.getParentId())) {
        // 当前遍历的节点为节点的上级节点
        if (treeNode.getParentId() == null) {
          // ROOT 节点为空,不做删除
          return false;
        } else if (isDeleteNode(relaseNode, treeNode)) {
          // 判断父节点在集合中是否存在
          return true;
        }
      }
    }
    return false;
  }

  /** 处理节点嫁接问题 */
  public static void nodeTransfer(Map<ITopic, TreeNode> relaseNode) {
    List<ITopic> removedTopics = new ArrayList<ITopic>();
    for (ITopic releaseItem : relaseNode.keySet()) {
      TreeNode treeNode = relaseNode.get(releaseItem);
      if (treeNode.getParentId() != null) {
        // 查找ParentId的节点
        for (ITopic parentItem : relaseNode.keySet()) {
          TreeNode parentTreeNode = relaseNode.get(parentItem);
          if (parentTreeNode.getId().equals(treeNode.getParentId())) {
            removedTopics.add(releaseItem);

            // 添加节点
            ITopic newTopic = ((TopicImpl) parentItem).getOwnedWorkbook().createTopic();
            newTopic.setTitleText(releaseItem.getTitleText());
            // 处理原始中的子节点
            XmindUtil.mergeChild(releaseItem, newTopic);
            // 从所有有特殊处理的节点集合中添加到当前节点
            TreeNodeUtil.mergeSpecialChild(relaseNode, newTopic, treeNode);
            parentItem.add(newTopic);
          }
        }
      }
    }

    removedTopics.forEach(
        item -> {
          item.getParent().remove(item);
        });
  }

  public static void mergeSpecialChild(
      Map<ITopic, TreeNode> relaseNode, ITopic newTopic, TreeNode treeNode) {
    for (ITopic iTopics : relaseNode.keySet()) {
      TreeNode topicsNode = relaseNode.get(iTopics);
      if (topicsNode.getParentId() != null && treeNode.getId().equals(topicsNode.getParentId())) {
        Boolean exist = false;
        for (ITopic childrenItem : newTopic.getAllChildren()) {
          if (childrenItem.getTitleText().equals(iTopics.getTitleText())) {
            exist = true;
          }
        }
        if (!exist) {
          ITopic newChinTopic = newTopic.getOwnedWorkbook().createTopic();
          newChinTopic.setTitleText(iTopics.getTitleText());
          // 查找当前节点下的下级节点
          mergeSpecialChild(relaseNode, newChinTopic, topicsNode);
          newTopic.add(newChinTopic);
        }
      }
    }
  }
}
